﻿namespace Yaaf.WP7.NativeAccess.ComWrapper.AllDevices.COM_NativeIO
{
    using System;
    using System.IO;

    public class File
    {
        private IntPtr m_hFile;
        private FileAccess m_fileAccess;
        private long m_length;

        internal File()
        {

        }

        internal int Read(byte[] buffer, int offset, int count)
        {
            int bytesRead = 0;
            int ret = NativeIODllInterop.ReadFile(Handle, buffer, count, offset, out bytesRead);

            return bytesRead;
        }

        internal long Seek(long offset, SeekOrigin origin)
        {
            MoveMethod method;

            switch (origin)
            {
                case SeekOrigin.Begin:
                    method = MoveMethod.Begin;
                    break;
                case SeekOrigin.Current:
                    method = MoveMethod.Current;
                    break;
                case SeekOrigin.End:
                    method = MoveMethod.End;
                    break;
                default:
                    throw new ArgumentOutOfRangeException("origin");
            }

            return NativeIODllInterop.SeekFile(Handle, (int)offset, method);
        }

        internal void Close()
        {
            NativeIODllInterop.CloseFile(m_hFile);
        }

        internal FileAccess FileAccess
        {
            get { return m_fileAccess; }
            private set { m_fileAccess = value; }
        }

        internal long Length
        {
            get { return m_length; }
            private set { m_length = value; }
        }

        internal long Position
        {
            get
            {
                return NativeIODllInterop.SeekFile(Handle, 0, MoveMethod.Current);
            }
        }

        internal IntPtr Handle
        {
            get { return m_hFile; }
            private set { m_hFile = value; }
        }

        public static FileStream Open(string lpFilename,
                                      FileAccess dwDesiredAccess,
                                      FileShare dwShareMode,
                                      CreationDisposition dwCreationDisposition)
        {
            var dwFlagsAndAttributes = FileAttributes.Normal;

            var file = new File();

            file.FileAccess = dwDesiredAccess;

            int ret = NativeIODllInterop.OpenFile(lpFilename,
                                          dwDesiredAccess,
                                          dwShareMode,
                                          dwCreationDisposition,
                                          dwFlagsAndAttributes,
                                          out file.m_hFile);

            if (file.Handle == IntPtr.Zero)
                throw new IOException("Could not open file");

            file.m_length = NativeIODllInterop.GetFileSize(file.Handle);

            return new FileStream(file);
        }

        public static byte[] ReadAllBytes(string filename)
        {
            using (FileStream fs = Open(filename, FileAccess.Read, FileShare.Read, CreationDisposition.OpenExisting))
            {
                using (BinaryReader bw = new BinaryReader(fs))
                {
                    return bw.ReadBytes((int)fs.Length);
                }
            }
        }

        public static string ReadAllText(string filename)
        {
            byte[] bytes = ReadAllBytes(filename);
            return System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
        }

        public static int Copy(string sourceFileName, string destFileName, bool failIfExists = false)
        {
            return NativeIODllInterop.CopyFile(sourceFileName, destFileName, failIfExists);
        }
    }
}
